package com.modernyuanshiren;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public interface IStatus<T extends IStatus<T, U>, U extends ISingleAction<T, U>> {
	List<IElement> getAllElements();

	List<IAction<T, U>> getAvailableActions();

	default Optional<IElement> getElementByPosition(int x) {
		return getAllElements()
				.stream()
				.filter(e -> e.getPosition().getX() == x
						&& e.getPosition().getY() == 0).findAny();
	}

	default Optional<IElement> getElementByPosition(int x, int y) {
		return getAllElements()
				.stream()
				.filter(e -> e.getPosition().getX() == x
						&& e.getPosition().getY() == y).findAny();
	}

	default List<IElement> getAllElementByPosition(int x, int y) {
		return getAllElements()
				.stream()
				.filter(e -> e.getPosition().getX() == x
						&& e.getPosition().getY() == y)
				.collect(Collectors.toList());
	}

	default Optional<IElement> getTranslateElement(IElement src, int dx) {
		return getAllElements()
				.stream()
				.filter(e -> e.getPosition().getX() == src.getPosition().getX()
						+ dx).findAny();
	}

	default Optional<IElement> leftOf(IElement src) {
		return getTranslateElement(src, -1);
	}

	default boolean is(Optional<IElement> element, String name) {
		return element.isPresent() && element.get().is(name);
	}

	default boolean is(Optional<IElement> element, IElement suppose) {
		return element.isPresent() && element.get().equals(suppose);
	}

	default Optional<IElement> rightOf(IElement src) {
		return getTranslateElement(src, 1);
	}

	default Optional<IElement> getTranslateElement(IElement src, int dx, int dy) {
		return getAllElements()
				.stream()
				.filter(e -> e.getPosition().getX() == src.getPosition().getX()
						+ dx
						&& e.getPosition().getY() == src.getPosition().getY()
								+ dy).findAny();
	}

	default List<IElement> getElementByName(String name) {
		return getAllElements().stream().filter(e -> e.getName().equals(name))
				.collect(Collectors.toList());
	}

	default boolean needCheckSymmetry() {
		return false;
	}
	
	default boolean checkSymmetry(T status) {
		return false;
	}
	
	default boolean isSymmetry() {
		return false;
	}

	boolean isEnd();
}
